﻿using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Shoozla.DataModel;
using Shoozla.DataModel.Helper;
using MahApps.Metro.Controls;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows;
using System.Windows.Input;


namespace Shoozla.ViewModel
{
    public enum SongFilter
    {
        All,
        Artwork,
        Empty
    }

    public class FolderListViewModel : ViewModelBase
    {
        #region Variables

        private SongFilter _displaySongFilter;
        private SongFilter DisplaySongFilter
        {
            get { return _displaySongFilter; }
            set {
                _displaySongFilter = value;
                switch (_displaySongFilter) //this filter the collection
                {
                    case SongFilter.Artwork: {
                        DisplayedSongs.Filter = item =>
                        {
                            var mp3 = item as Mp3File;
                            if(mp3.FileName.FullName.StartsWith(SelectedFolder.FullName) && mp3.HasCover)
                                return true;
                            return false;
                        };
                        break; }
                    case SongFilter.Empty: {
                        DisplayedSongs.Filter = item =>
                        {
                            var mp3 = item as Mp3File;
                            if (mp3.FileName.FullName.StartsWith(SelectedFolder.FullName) && mp3.HasCover)
                                return false;
                            return true;
                        };
                        break;
                    }
                    default : {
                        DisplayedSongs.Filter = item =>
                        {
                           var mp3 = item as Mp3File;
                           if (mp3.FileName.FullName.StartsWith(SelectedFolder.FullName))
                             return true;
                           return false;
                        };
                        break;
                    }
                }

                if (DisplayedSongs.IsEmpty)
                    ShowHint = true; //no songs selected
                else
                    ShowHint = false;
            }

           
        } //to filter the display


        private DirectoryInfo _selectedFolder;
        public DirectoryInfo SelectedFolder
        {
            get
            {
                return _selectedFolder;
            }
            set{
   
                _selectedFolder = value;
                
                //refresh current list, same filter as selected
                DisplaySongFilter = DisplaySongFilter; 

            }
        
        }

   
        private ListCollectionView _displayedSongs; //items displayed     
        /// <summary>
        /// Collection with all Mp3, used for display purpouse (filter and sort)
        /// </summary>
        public ListCollectionView DisplayedSongs
        {
            get
            {
                return _displayedSongs;
            }

            set {
                _displayedSongs = value;

                DisplaySongFilter = SongFilter.All;
                SelectedFolder = SelectedFolder; //trigger the display of the selected folder (to preserve the filter used)

                if (_displayedSongs.IsEmpty)
                    ShowHint = true; //no songs selected
                else
                    ShowHint = false;

                OnPropertyChanged("DisplayedSongs");

               
            }
        }


        private bool _showHint;

        /// <summary>
        /// Used to display help messages on the UI
        /// </summary>
        public bool ShowHint
        {
            get { return _showHint; }
            set
            {
                if (value != _showHint)
                {
                    _showHint = value;
                    OnPropertyChanged("ShowHint");
                }
            }
        } 

        private bool _allChildSelected;
        public bool AllChildSelected
        {
            get { return ((ObservableCollection<Mp3File>)DisplayedSongs.SourceCollection).All<Mp3File>((m) => m.IsSelected); } //not working
            set {
                if (value != _allChildSelected)
                {
                    _allChildSelected = value;
                    if (_allChildSelected)
                        DoCmdSelectAll();
                    else
                        DoCmdSelectNone();
                    OnPropertyChanged("AllChildSelected");
                }
            }
        }

        #endregion

        #region Constructors

        public FolderListViewModel(Window owner) : base(null,owner) {
            DisplayedSongs = new ListCollectionView(new List<Mp3File>()); 
            DisplaySongFilter = SongFilter.All;
            ShowHint = true;
            AllChildSelected = false;
        }

       
        #endregion

        #region Commands

        //- not used anymore
        private RelayCommand _CmdSelectAll;
        public RelayCommand CmdSelectAll
        {
            get
            {
                if (_CmdSelectAll == null)
                {
                    _CmdSelectAll = new RelayCommand(param => DoCmdSelectAll(), param => CanExecuteCurrentItemsOp());
                }
                return _CmdSelectAll;
            }
        }

        //- not used anymore
        private RelayCommand _CmdSelectNone;
        public RelayCommand CmdSelectNone
        {
            get
            {
                if (_CmdSelectNone == null)
                {
                    _CmdSelectNone = new RelayCommand(param => DoCmdSelectNone(), param => CanExecuteCurrentItemsOp());
                }
                return _CmdSelectNone;
            }
        }

        private RelayCommand _CmdShowAll;
        public RelayCommand CmdShowAll
        {
            get
            {
                if (_CmdShowAll == null)
                {
                    _CmdShowAll = new RelayCommand(param => DoCmdShowAll(), param => DisplaySongFilter != SongFilter.All);
                }
                return _CmdShowAll;
            }
        }

        private RelayCommand _CmdShowCovered;
        public RelayCommand CmdShowCovered
        {
            get
            {
                if (_CmdShowCovered == null)
                {
                    _CmdShowCovered = new RelayCommand(param => DoCmdShowCovered(), param => DisplaySongFilter != SongFilter.Artwork);
                }
                return _CmdShowCovered;
            }
        }

        private RelayCommand _CmdShowUnCovered;
        public RelayCommand CmdShowUnCovered
        {
            get
            {
                if (_CmdShowUnCovered == null)
                {
                    _CmdShowUnCovered = new RelayCommand(param => DoCmdShowUnCovered(), param => DisplaySongFilter != SongFilter.Empty);
                }
                return _CmdShowUnCovered;
            }
        }


        protected bool CanExecuteItemsOp()
        {
            if (AppModel.Songs.Count > 0)
                return true;
            else
                return false;
        }

        protected bool CanExecuteCurrentItemsOp()
        {
            if (!DisplayedSongs.IsEmpty)
                return true;
            else
                return false;
        }

        #endregion

        #region Do Commands

        protected void DoCmdSelectAll()
        {
            foreach (Mp3File m in DisplayedSongs)
                m.IsSelected = true;                   
        }

        protected void DoCmdSelectNone()
        {
            foreach (Mp3File m in DisplayedSongs)
                m.IsSelected = false;
        }

        protected void DoCmdShowAll()
        {
            DisplaySongFilter = SongFilter.All;

        }

        private void DoCmdShowCovered()
        {
            DisplaySongFilter = SongFilter.Artwork;
        }

        private void DoCmdShowUnCovered()
        {
            DisplaySongFilter = SongFilter.Empty;
        }


        public void LoadMp3FromFolders(DirectoryInfo folder)
        {
            System.Windows.Input.Cursor currentCur = Mouse.OverrideCursor;
            Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;

            AppModel.ResetApplication();
            AllChildSelected = false;
            try
            {
                SelectedFolder = folder;
                OpenFolderInternal(folder);
                if (AppModel.ProgressOperationQueue.Count > 0)
                    AppModel.StartProgressBarInternal(AppModel.ProgressOperationQueue.ToList<IProgressOperation>());
               
            }
            catch (UnauthorizedAccessException accEx)
            {
                AppModel.LogEntry("[ERROR] AddFolderToView: " + accEx.Message);
                MetroMessageBox.MetroShow("", "You don't have the permission to open the selected folder or one of its subfolders!", true, App.MainView, MessageIcon.Warning, false);
            }
            finally
            {
                Mouse.OverrideCursor = currentCur;
            }
        }

        //NOTE reading files from disk
        private void OpenFolderInternal(DirectoryInfo dir)
        {

            if (dir != null)
            {

                AppModel.FoldersRead.Add(dir);

                FolderScanner mp3FolderScanner = new FolderScanner(AppModel.MainCancellationTokenSource, AppModel.Mp3Processor);
                mp3FolderScanner.Completed += delegate(object sender, ProgressOperationEventArgs e)
                {
                    AppModel.AddSongsToCollection(mp3FolderScanner.Mp3FileInFolder);
                    if (AppModel.ProgressOperationQueue.Contains(mp3FolderScanner))
                        AppModel.ProgressOperationQueue.Remove(mp3FolderScanner); //work done, change the application status (to IDLE)

                    DisplayFolderContent(dir);
                };

                if (mp3FolderScanner.AddFolderToScanner(dir) > 20)
                {
                    //Display the ProgressBar only if there are have at least X mp3 file
                    //creating a queue with all the big folders
                    AppModel.ProgressOperationQueue.Add(mp3FolderScanner);
                }
                else
                {
                    //read the folder now
                    mp3FolderScanner.Start();
                }

            }
        }
      

        private void DisplayFolderContent(DirectoryInfo dir)
        {
            if (AppModel.IsAppWorking)
                return; //do not refresh, collection changing

            ////folder already read just refresh the view
            
            DispatcherUIThread.BeginInvoke((Action)(() =>
            {
                DisplayedSongs.Filter = item =>
                {
                    Mp3File m = item as Mp3File;
                    if (m.FileName.DirectoryName.StartsWith(dir.FullName))
                        return true;
                    else
                        return false;
                };

            }));
        }


        #endregion

        private void SearchSingleCover(Mp3File song)
        {
            Uri coverUri = AppModel.CoverSearcher.FindSingleCover(song);
            if (coverUri != null)
                song.ImageUrl = coverUri;       
          //  RaiseItemRead();
        }


    }
}
